var app = {},
    CryptoJS = CryptoJS || function (e, t) {
        var n = {},
            i = n.lib = {},
            r = function () {},
            o = i.Base = {
                extend: function (e) {
                    r.prototype = this;
                    var t = new r;
                    return e && t.mixIn(e), t.hasOwnProperty("init") || (t.init = function () {
                        t.$super.init.apply(this, arguments)
                    }), t.init.prototype = t, t.$super = this, t
                },
                create: function () {
                    var e = this.extend();
                    return e.init.apply(e, arguments), e
                },
                init: function () {},
                mixIn: function (e) {
                    for (var t in e) e.hasOwnProperty(t) && (this[t] = e[t]);
                    e.hasOwnProperty("toString") && (this.toString = e.toString)
                },
                clone: function () {
                    return this.init.prototype.extend(this)
                }
            },
            s = i.WordArray = o.extend({
                init: function (e, t) {
                    e = this.words = e || [], this.sigBytes = null != t ? t : 4 * e.length
                },
                toString: function (e) {
                    return (e || l).stringify(this)
                },
                concat: function (e) {
                    var t = this.words,
                        n = e.words,
                        i = this.sigBytes;
                    if (e = e.sigBytes, this.clamp(), i % 4)
                        for (var r = 0; r < e; r++) t[i + r >>> 2] |= (n[r >>> 2] >>> 24 - r % 4 * 8 & 255) << 24 - (i + r) % 4 * 8;
                    else if (65535 < n.length)
                        for (r = 0; r < e; r += 4) t[i + r >>> 2] = n[r >>> 2];
                    else t.push.apply(t, n);
                    return this.sigBytes += e, this
                },
                clamp: function () {
                    var t = this.words,
                        n = this.sigBytes;
                    t[n >>> 2] &= 4294967295 << 32 - n % 4 * 8, t.length = e.ceil(n / 4)
                },
                clone: function () {
                    var e = o.clone.call(this);
                    return e.words = this.words.slice(0), e
                },
                random: function (t) {
                    for (var n = [], i = 0; i < t; i += 4) n.push(4294967296 * e.random() | 0);
                    return new s.init(n, t)
                }
            }),
            a = n.enc = {},
            l = a.Hex = {
                stringify: function (e) {
                    var t = e.words;
                    e = e.sigBytes;
                    for (var n = [], i = 0; i < e; i++) {
                        var r = t[i >>> 2] >>> 24 - i % 4 * 8 & 255;
                        n.push((r >>> 4).toString(16)), n.push((15 & r).toString(16))
                    }
                    return n.join("")
                },
                parse: function (e) {
                    for (var t = e.length, n = [], i = 0; i < t; i += 2) n[i >>> 3] |= parseInt(e.substr(i, 2), 16) << 24 - i % 8 * 4;
                    return new s.init(n, t / 2)
                }
            },
            d = a.Latin1 = {
                stringify: function (e) {
                    var t = e.words;
                    e = e.sigBytes;
                    for (var n = [], i = 0; i < e; i++) n.push(String.fromCharCode(t[i >>> 2] >>> 24 - i % 4 * 8 & 255));
                    return n.join("")
                },
                parse: function (e) {
                    for (var t = e.length, n = [], i = 0; i < t; i++) n[i >>> 2] |= (255 & e.charCodeAt(i)) << 24 - i % 4 * 8;
                    return new s.init(n, t)
                }
            },
            c = a.Utf8 = {
                stringify: function (e) {
                    try {
                        return decodeURIComponent(escape(d.stringify(e)))
                    } catch (e) {
                        throw Error("Malformed UTF-8 data")
                    }
                },
                parse: function (e) {
                    return d.parse(unescape(encodeURIComponent(e)))
                }
            },
            u = i.BufferedBlockAlgorithm = o.extend({
                reset: function () {
                    this._data = new s.init, this._nDataBytes = 0
                },
                _append: function (e) {
                    "string" == typeof e && (e = c.parse(e)), this._data.concat(e), this._nDataBytes += e.sigBytes
                },
                _process: function (t) {
                    var n = this._data,
                        i = n.words,
                        r = n.sigBytes,
                        o = this.blockSize,
                        a = r / (4 * o);
                    if (t = (a = t ? e.ceil(a) : e.max((0 | a) - this._minBufferSize, 0)) * o, r = e.min(4 * t, r), t) {
                        for (var l = 0; l < t; l += o) this._doProcessBlock(i, l);
                        l = i.splice(0, t), n.sigBytes -= r
                    }
                    return new s.init(l, r)
                },
                clone: function () {
                    var e = o.clone.call(this);
                    return e._data = this._data.clone(), e
                },
                _minBufferSize: 0
            });
        i.Hasher = u.extend({
            cfg: o.extend(),
            init: function (e) {
                this.cfg = this.cfg.extend(e), this.reset()
            },
            reset: function () {
                u.reset.call(this), this._doReset()
            },
            update: function (e) {
                return this._append(e), this._process(), this
            },
            finalize: function (e) {
                return e && this._append(e), this._doFinalize()
            },
            blockSize: 16,
            _createHelper: function (e) {
                return function (t, n) {
                    return new e.init(n).finalize(t)
                }
            },
            _createHmacHelper: function (e) {
                return function (t, n) {
                    return new p.HMAC.init(e, n).finalize(t)
                }
            }
        });
        var p = n.algo = {};
        return n
    }(Math);
! function (e) {
    function t(e, t, n, i, r, o, s) {
        return ((e = e + (t & n | ~t & i) + r + s) << o | e >>> 32 - o) + t
    }

    function n(e, t, n, i, r, o, s) {
        return ((e = e + (t & i | n & ~i) + r + s) << o | e >>> 32 - o) + t
    }

    function i(e, t, n, i, r, o, s) {
        return ((e = e + (t ^ n ^ i) + r + s) << o | e >>> 32 - o) + t
    }

    function r(e, t, n, i, r, o, s) {
        return ((e = e + (n ^ (t | ~i)) + r + s) << o | e >>> 32 - o) + t
    }
    for (var o = CryptoJS, s = (l = o.lib).WordArray, a = l.Hasher, l = o.algo, d = [], c = 0; 64 > c; c++) d[c] = 4294967296 * e.abs(e.sin(c + 1)) | 0;
    l = l.MD5 = a.extend({
        _doReset: function () {
            this._hash = new s.init([1732584193, 4023233417, 2562383102, 271733878])
        },
        _doProcessBlock: function (e, o) {
            for (var s = 0; 16 > s; s++) {
                var a = e[l = o + s];
                e[l] = 16711935 & (a << 8 | a >>> 24) | 4278255360 & (a << 24 | a >>> 8)
            }
            s = this._hash.words;
            var l = e[o + 0],
                c = (a = e[o + 1], e[o + 2]),
                u = e[o + 3],
                p = e[o + 4],
                f = e[o + 5],
                g = e[o + 6],
                m = e[o + 7],
                h = e[o + 8],
                w = e[o + 9],
                b = e[o + 10],
                v = e[o + 11],
                y = e[o + 12],
                x = e[o + 13],
                E = e[o + 14],
                T = e[o + 15],
                P = t(P = s[0], M = s[1], j = s[2], S = s[3], l, 7, d[0]),
                S = t(S, P, M, j, a, 12, d[1]),
                j = t(j, S, P, M, c, 17, d[2]),
                M = t(M, j, S, P, u, 22, d[3]);
            P = t(P, M, j, S, p, 7, d[4]), S = t(S, P, M, j, f, 12, d[5]), j = t(j, S, P, M, g, 17, d[6]), M = t(M, j, S, P, m, 22, d[7]), P = t(P, M, j, S, h, 7, d[8]), S = t(S, P, M, j, w, 12, d[9]), j = t(j, S, P, M, b, 17, d[10]), M = t(M, j, S, P, v, 22, d[11]), P = t(P, M, j, S, y, 7, d[12]), S = t(S, P, M, j, x, 12, d[13]), j = t(j, S, P, M, E, 17, d[14]), P = n(P, M = t(M, j, S, P, T, 22, d[15]), j, S, a, 5, d[16]), S = n(S, P, M, j, g, 9, d[17]), j = n(j, S, P, M, v, 14, d[18]), M = n(M, j, S, P, l, 20, d[19]), P = n(P, M, j, S, f, 5, d[20]), S = n(S, P, M, j, b, 9, d[21]), j = n(j, S, P, M, T, 14, d[22]), M = n(M, j, S, P, p, 20, d[23]), P = n(P, M, j, S, w, 5, d[24]), S = n(S, P, M, j, E, 9, d[25]), j = n(j, S, P, M, u, 14, d[26]), M = n(M, j, S, P, h, 20, d[27]), P = n(P, M, j, S, x, 5, d[28]), S = n(S, P, M, j, c, 9, d[29]), j = n(j, S, P, M, m, 14, d[30]), P = i(P, M = n(M, j, S, P, y, 20, d[31]), j, S, f, 4, d[32]), S = i(S, P, M, j, h, 11, d[33]), j = i(j, S, P, M, v, 16, d[34]), M = i(M, j, S, P, E, 23, d[35]), P = i(P, M, j, S, a, 4, d[36]), S = i(S, P, M, j, p, 11, d[37]), j = i(j, S, P, M, m, 16, d[38]), M = i(M, j, S, P, b, 23, d[39]), P = i(P, M, j, S, x, 4, d[40]), S = i(S, P, M, j, l, 11, d[41]), j = i(j, S, P, M, u, 16, d[42]), M = i(M, j, S, P, g, 23, d[43]), P = i(P, M, j, S, w, 4, d[44]), S = i(S, P, M, j, y, 11, d[45]), j = i(j, S, P, M, T, 16, d[46]), P = r(P, M = i(M, j, S, P, c, 23, d[47]), j, S, l, 6, d[48]), S = r(S, P, M, j, m, 10, d[49]), j = r(j, S, P, M, E, 15, d[50]), M = r(M, j, S, P, f, 21, d[51]), P = r(P, M, j, S, y, 6, d[52]), S = r(S, P, M, j, u, 10, d[53]), j = r(j, S, P, M, b, 15, d[54]), M = r(M, j, S, P, a, 21, d[55]), P = r(P, M, j, S, h, 6, d[56]), S = r(S, P, M, j, T, 10, d[57]), j = r(j, S, P, M, g, 15, d[58]), M = r(M, j, S, P, x, 21, d[59]), P = r(P, M, j, S, p, 6, d[60]), S = r(S, P, M, j, v, 10, d[61]), j = r(j, S, P, M, c, 15, d[62]), M = r(M, j, S, P, w, 21, d[63]);
            s[0] = s[0] + P | 0, s[1] = s[1] + M | 0, s[2] = s[2] + j | 0, s[3] = s[3] + S | 0
        },
        _doFinalize: function () {
            var t = this._data,
                n = t.words,
                i = 8 * this._nDataBytes,
                r = 8 * t.sigBytes;
            n[r >>> 5] |= 128 << 24 - r % 32;
            var o = e.floor(i / 4294967296);
            for (n[15 + (r + 64 >>> 9 << 4)] = 16711935 & (o << 8 | o >>> 24) | 4278255360 & (o << 24 | o >>> 8), n[14 + (r + 64 >>> 9 << 4)] = 16711935 & (i << 8 | i >>> 24) | 4278255360 & (i << 24 | i >>> 8), t.sigBytes = 4 * (n.length + 1), this._process(), n = (t = this._hash).words, i = 0; 4 > i; i++) r = n[i], n[i] = 16711935 & (r << 8 | r >>> 24) | 4278255360 & (r << 24 | r >>> 8);
            return t
        },
        clone: function () {
            var e = a.clone.call(this);
            return e._hash = this._hash.clone(), e
        }
    }), o.MD5 = a._createHelper(l), o.HmacMD5 = a._createHmacHelper(l)
}(Math);
"use strict";
app = app || require("./firefox/firefox");
(utils = "undefined" == typeof exports ? {} : exports).debounce = function (e, t) {
    let n, i = !1;

    function r() {
        i || (app.timer.clearTimeout(n), i = !0, e.apply(this, arguments), n = app.timer.setTimeout((function () {
            i = !1
        }), t))
    }
    return r.now = function () {
        i = !1, r.apply(this, arguments)
    }, r
}, utils.validate = function (e) {
    try {
        return !!new app.URL(e).host
    } catch (e) {
        return !1
    }
}, utils.assign = function (e, t, n, i) {
    let r = i;
    return Object.defineProperty(e, t, {
        get: function () {
            return r
        },
        set: function (e) {
            e !== r && (r = e, n.emit(t, r))
        }
    }), utils
}, utils.EventEmitter = function () {
    let e = function () {
        this.listeners = {}, this.onces = {}
    };
    return e.prototype.on = function (e, t) {
        this.listeners[e] = this.listeners[e] || [], this.listeners[e].push(t)
    }, e.prototype.once = function (e, t) {
        this.onces[e] = this.onces[e] || [], this.onces[e].push(t)
    }, e.prototype.emit = function (e) {
        let t = Array.prototype.slice.call(arguments),
            n = t.splice(1);
        this.listeners[e] && this.listeners[e].forEach((function (e) {
            try {
                e.apply(this, n)
            } catch (e) {}
        })), this.onces[e] && (this.onces[e].forEach((function (e) {
            try {
                e.apply(this, n)
            } catch (e) {}
        })), this.onces[e] = [])
    }, e.prototype.removeListener = function (e, t) {
        if (this.listeners[e]) {
            var n = this.listeners[e].indexOf(t); - 1 !== n && this.listeners[e].splice(n, 1)
        }
    }, e.prototype.removeAllListeners = function () {
        this.listeners = {}, this.onces = {}
    }, e
}(), utils.spy = function (e, t) {
    return e.then((function (e) {
        let n = t(null, e);
        return n && "then" in n ? n.then((() => e), (() => e)) : e
    }), (function (e) {
        let n = t(e, null);
        if (n && "then" in n) return n.then((function () {
            throw e
        }), (function () {
            throw e
        }));
        throw e
    }))
}, utils.CError = function (e, t, n) {
    this.code = t || -1, this.message = e || -1, Object.keys(n || {}).forEach((e => this[e] = n[e]))
}, utils.CError.prototype = Error.prototype;
app = app || require("./firefox/firefox");
(config = "undefined" == typeof exports ? {} : exports).defaults = {}, config.define = function () {
    let e = {},
        t = {};
    return function (n, i, r) {
        let o = n.split("."),
            s = o.pop();
        t[n] = typeof i, o.reduce(((e, t) => (e[t] || (e[t] = {}), e[t])), config.defaults)[s] = i;
        let a = o.reduce(((e, t) => (e[t] || (e[t] = {}), e[t])), config);
        Object.defineProperty(a, s, {
            enumerable: !0,
            get: function () {
                let i = e[n];
                if (void 0 === i && (i = app.storage.read("pref." + n), void 0 !== i && ("number" === t[n] && (i = +i), "boolean" === t[n] && (i = "false" !== i && !1 !== i))), void 0 === i) try {
                    i = n.split(".").reduce(((e, t) => e[t]), config.defaults)
                } catch (e) {}
                return e[n] = i, i
            },
            set: function (i) {
                let o = typeof (i = (r || function (e) {
                    return e
                })(i));
                if (o !== t[n]) throw Error(`type does not match; ${o} !== ${t[n]}`);
                app.storage.write("pref." + n, i), e[n] = i
            }
        })
    }
}(), config.defineInt = function (e, t, n, i) {
    config.define(e, t, (function (e) {
        let t = Math.max(+e, n || 1);
        return i && (t = Math.min(t, i)), isNaN(t) ? e : t
    }))
}, config.get = function (e) {
    return e.split(".").reduce(((e, t) => e[t]), config)
}, config.reset = function (e) {
    let t = e.split(".").reduce(((e, t) => e[t]), config.defaults);
    config.set(e, t)
}, config.set = function (e, t) {
    let n = e.split("."),
        i = n.pop();
    n.reduce(((e, t) => (e[t] || (e[t] = {}), e[t])), config)[i] = t
}, config.list = function () {
    let e = [];
    return function t(n, i) {
        return Object.keys(n).filter((e => null !== n[e])).forEach((function (r) {
            let o = i ? i + "." : "";
            "object" == typeof n[r] ? t(n[r], o + r) : e.push({
                name: o + r,
                value: n[r],
                type: typeof n[r],
                title: config.titles[o + r] || "-"
            })
        })), e
    }(config)
}, config.defineInt("mwget.percent.rate-total", 1), config.defineInt("mwget.percent.rate-individual", 1), config.define("mwget.notice-batch-download", !0), config.defineInt("wget.threads", 3), config.defineInt("wget.timeout", 30, 10), config.defineInt("wget.retries", 30), config.defineInt("wget.update", 1), config.defineInt("wget.pause", 500, 100), config.defineInt("wget.short-pause", 100), config.defineInt("wget.write-size", 204800, 1024), config.defineInt("wget.min-segment-size", 51200, 1024), config.defineInt("wget.max-segment-size", 104857600, 102400), config.defineInt("wget.max-size-md5", 524288e3, 1, 524288e3), config.define("wget.directory", ""), config.define("wget.notice-download", !0), config.define("wget.pause-on-exists", !1), config.defineInt("icon.timeout", 5), config.define("triggers.pause.enabled", !0), config.defineInt("triggers.pause.value", 3, 1, 10), config.define("triggers.start.enabled", !0), config.defineInt("triggers.start.value", 3, 1, 10), config.define("triggers.success.enabled", !1), config.defineInt("triggers.success.value", 60, 10), config.define("triggers.fail.enabled", !1), config.defineInt("triggers.fail.value", 180, 10), config.define("triggers.play-single.enabled", !1), config.define("triggers.play-combined.enabled", !0), config.define("welcome.version", ""), config.define("welcome.show", !0), config.welcome.timeout = 3, config.define("manager.launch-if-done", !0), config.define("preview.external.image.path", ""), config.define("preview.external.image.args", ""), config.define("preview.external.audio.path", ""), config.define("preview.external.audio.args", ""), config.define("preview.external.video.path", ""), config.define("preview.external.video.args", ""), config.define("network.proxy-server", "", (function (e) {
    if (e) {
        if (/.\:\d+$/.test(e)) return e;
        app.notification("Format: socks5://host:port")
    }
    return ""
}));
var WebExtensions = WebExtensions || navigator.userAgent.includes("Chrome") ? chrome : browser;
app = new utils.EventEmitter;
Object.values || (Object.values = function (e) {
        let t = [];
        for (let n in e) t.push(e[n]);
        return t
    }), app.globals = {
        browser: "chrome",
        extension: !1,
        open: !1,
        reveal: !1,
        folder: !0,
        referrer: "X-Referer"
    }, Promise.defer || (Promise.defer = function () {
        let e = {},
            t = new Promise((function (t, n) {
                e.resolve = t, e.reject = n
            }));
        return e.promise = t, e
    }), app.Promise = Promise, app.XMLHttpRequest = window.XMLHttpRequest, app.fetch = (e, t) => fetch(e, t), app.EventEmitter = utils.EventEmitter, app.timer = window, app.URL = window.URL, app.canvas = () => null, app.storage = function () {
        let e = {};
        return localStorage.getItem("dlapp.storage") && (e = JSON.parse(localStorage.getItem("dlapp.storage"))), {
            read: t => e[t],
            write: function (t, n) {
                e[t] = n;
                let i = {};
                i[t] = n, localStorage.setItem("dlapp.storage", JSON.stringify(i))
            }
        }
    }(), app.button = {
        onCommand: function () {},
        icon: null,
        label: null,
        badge: null
    }, app.tab = {
        open: function () {},
        list: () => Promise.resolve([]),
        reload: () => Promise.resolve(),
        activate: () => Promise.resolve()
    }, app.menu = function () {},
    function (e) {
        let t = new XMLHttpRequest;
        t.open("GET", "dlm/data/assets/mime.json"), t.responseType = "json", t.onloadend = function () {
            e = t.response || e
        }, t.send(), Object.defineProperty(app, "mimes", {
            get: function () {
                return e
            }
        })
    }({}), app.getURL = e => WebExtensions.runtime.getURL("/data/" + e), app.version = () => Promise.resolve(WebExtensions.runtime.getManifest().version), app.platform = function () {
        let e = /Chrome\/[\d\.]*/.exec(navigator.userAgent),
            t = /OPR\/[\d\.]*/.exec(navigator.userAgent);
        return `${t?t[0].replace("OPR/","OPR "):e[0].replace("Chrome/","Chrome ")} on ${navigator.platform}`
    }, app.manager = {
        send: (e, t) => WebExtensions.runtime.sendMessage({
            method: e + "@ui",
            data: t
        }),
        sendTab: (e, t) => {
            if (!t.id) return !1;
            WebExtensions.tabs.sendMessage(parseInt(t.id), {
                method: e + "@ui",
                data: t
            })
        },
        receive: (e, t) => WebExtensions.runtime.onMessage.addListener((function (n, i) {
            e + "@ui" === n.method && i.url !== document.location.href && t.call(i.tab, n.data)
        }))
    }, app.add = {
        send: (e, t) => WebExtensions.runtime.sendMessage({
            method: e + "@ad",
            data: t
        }),
        receive: (e, t) => WebExtensions.runtime.onMessage.addListener((function (n, i) {
            e + "@ad" === n.method && i.url !== document.location.href && t.call(i.tab, n.data)
        }))
    }, app.info = {
        send: (e, t) => WebExtensions.runtime.sendMessage({
            method: e + "@if",
            data: t
        }),
        sendTab: (e, t) => {
            if (!t.id) return !1;
            WebExtensions.tabs.sendMessage(parseInt(t.id), {
                method: e + "@if",
                data: t
            })
        },
        receive: (e, t) => WebExtensions.runtime.onMessage.addListener((function (n, i) {
            e + "@if" === n.method && i.url !== document.location.href && t.call(i.tab, n.data)
        }))
    }, app.modify = {
        send: (e, t) => WebExtensions.runtime.sendMessage({
            method: e + "@md",
            data: t
        }),
        sendTab: (e, t) => {
            if (!t.id) return !1;
            WebExtensions.tabs.sendMessage(parseInt(t.id), {
                method: e + "@md",
                data: t
            })
        },
        receive: (e, t) => {
            WebExtensions.runtime.onMessage.addListener((function (n, i) {
                e + "@md" === n.method && i.url !== document.location.href && t.call(i.tab, n.data)
            }))
        }
    }, app.triggers = {
        send: (e, t) => WebExtensions.runtime.sendMessage({
            method: e + "@tr",
            data: t
        }),
        receive: (e, t) => WebExtensions.runtime.onMessage.addListener((function (n, i) {
            e + "@tr" === n.method && i.url !== document.location.href && t.call(i.tab, n.data)
        }))
    }, app.about = {
        send: (e, t) => WebExtensions.runtime.sendMessage({
            method: e + "@ab",
            data: t
        }),
        receive: (e, t) => WebExtensions.runtime.onMessage.addListener((function (n, i) {
            e + "@ab" === n.method && i.url !== document.location.href && t.call(i.tab, n.data)
        }))
    }, app.extract = {
        send: (e, t) => WebExtensions.runtime.sendMessage({
            method: e + "@ex",
            data: t
        }),
        receive: (e, t) => WebExtensions.runtime.onMessage.addListener((function (n, i) {
            e + "@ex" === n.method && i.url !== document.location.href && t.call(i.tab, n.data)
        }))
    }, app.preview = {
        send: (e, t) => WebExtensions.runtime.sendMessage({
            method: e + "@pr",
            data: t
        }),
        receive: (e, t) => WebExtensions.runtime.onMessage.addListener((function (n, i) {
            e + "@pr" === n.method && i.url !== document.location.href && t.call(i.tab, n.data)
        }))
    }, app.config = {
        send: (e, t) => WebExtensions.runtime.sendMessage({
            method: e + "@cf",
            data: t
        }),
        receive: (e, t) => WebExtensions.runtime.onMessage.addListener((function (n, i) {
            e + "@cf" === n.method && i.url !== document.location.href && t.call(i.tab, n.data)
        }))
    }, app.logs = {
        send: (e, t) => WebExtensions.runtime.sendMessage({
            method: e + "@lg",
            data: t
        }),
        receive: (e, t) => WebExtensions.runtime.onMessage.addListener((function (n, i) {
            e + "@lg" === n.method && i.url !== document.location.href && t.call(i.tab, n.data)
        }))
    }, app.play = e => {
        new Audio(WebExtensions.runtime.getURL("/dlm/data/" + e)).play()
    }, app.arguments = function () {
        let e = [],
            t = [];
        return WebExtensions.runtime && WebExtensions.runtime.onMessageExternal && WebExtensions.runtime.onMessageExternal.addListener((function (n, i) {
                "register" === n.cmd ? (app.runtime.register(i.id), n.support && -1 !== n.support.indexOf("icon") && (app.canvas = () => document.createElement("canvas"), icon.register())) : e.length ? e.forEach((e => e(n))) : t.push(n)
            })),
            function (n) {
                e.push(n), t.forEach((e => n(e))), t = []
            }
    }(), window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem, app.fileSystem = {
        file: {
            exists: function (e, t) {
                return new Promise((function (n) {
                    e.getFile(t, {
                        create: !0,
                        exclusive: !0
                    }, (() => n(!1)), (() => n(!0)))
                }))
            },
            create: function (e, t) {
                return new Promise((function (n, i) {
                    e.getFile(t, {
                        create: !0,
                        exclusive: !1
                    }, (e => n(e)), (e => i(e)))
                }))
            },
            truncate: function (e, t) {
                return new Promise((function (n, i) {
                    e.createWriter((function (e) {
                        e.onwrite = () => n(), e.onerror = e => i(e), e.truncate(t)
                    }))
                }))
            },
            write: function (e, t, n) {
                return new Promise((function (i, r) {
                    e.createWriter((function (e) {
                        let o = new Blob(n, {
                            type: "application/octet-stream"
                        });
                        e.onerror = e => r(e), e.onwrite = () => i(), e.seek(t), e.write(o)
                    }), (e => r(e)))
                }))
            },
            md5: function (e, t) {
                return new Promise((function (n, i) {
                    return e ? t > 52428800 ? n("MD5 calculation is skipped") : void e.file((function (e) {
                        let t = new FileReader;
                        t.onloadend = function () {
                            n(CryptoJS.MD5(CryptoJS.enc.Latin1.parse(this.result)).toString())
                        }, t.readAsBinaryString(e)
                    }), (e => i(e))) : n("file is not found")
                }))
            },
            rename: function (e, t, n) {
                return new Promise(((i, r) => e.moveTo(t, n, i, r)))
            },
            remove: function (e) {
                return new Promise(((t, n) => e.remove(t, n)))
            },
            launch: () => Promise.reject(new Error("not implemented")),
            reveal: () => Promise.reject(new Error("not implemented")),
            close: () => Promise.resolve(),
            toURL: e => new Promise((function (t, n) {
                e.file((e => t(URL.createObjectURL(e))), (e => n(e)))
            }))
        },
        root: {
            internal: function (e) {
                return new Promise((function (t, n) {
                    navigator.webkitTemporaryStorage.requestQuota(e, (function (i) {
                        i === e ? window.requestFileSystem(window.TEMPORARY, e, (function (e) {
                            t(e.root)
                        }), (e => n(e))) : n(new Error("cannot allocate space in the internal storage"))
                    }))
                }))
            },
            external: function () {
                return new Promise((function (e, t) {
                    WebExtensions.storage.local.get(null, (function (n) {
                        if (n.folder && config.wget.directory) try {
                            WebExtensions.fileSystem.restoreEntry(n.folder, (function (n) {
                                n ? e(n) : t(new Error("storage.folder is undefined"))
                            }))
                        } catch (e) {
                            t(e)
                        } else t(new Error("either storage.folder or config.wget.directory is undefined"))
                    }))
                }))
            }
        }
    }, app.process = () => Promise.reject("not supported"), app.webRequest = function () {
        let e = {
            media: function () {}
        };
        return app.extract.receive("media", (t => e.media(t))), {
            media: t => e.media = t
        }
    }(), app.crequire = function (e, t) {
        return new Promise((function (n, i) {
            let r = document.createElement("script");
            r.src = "dlm/lib/" + t[0] + ".js", r.onload = () => n(window[e]), r.onerorr = () => i(), document.body.appendChild(r)
        }))
    };
WebExtensions = WebExtensions || navigator.userAgent.includes("Chrome") ? chrome : browser;
app.once("load", (function () {
    let e = document.createElement("script");
    document.body.appendChild(e), e.src = "lib/common.js"
})), app.notification = e => {}, app.OS = function (e) {
    return document.body.appendChild(e), {
        clipboard: {
            get: function () {
                let t = "";
                return e.value = "", e.select(), document.execCommand("paste") && (t = e.value), Promise.resolve(t)
            }
        }
    }
}(document.createElement("textarea")), app.startup = function () {
    let e, t;

    function n() {
        "startup" !== e && "install" !== e || t && t()
    }
    return WebExtensions.runtime.onInstalled.addListener((function (t) {
            e = t.reason, n()
        })), WebExtensions.runtime.onStartup.addListener((function () {
            e = "startup", n()
        })),
        function (e) {
            t = e, n()
        }
}();
WebExtensions = WebExtensions || navigator.userAgent.includes("Chrome") ? chrome : browser;
Object.defineProperty(app.button, "icon", {
    set: function (e) {
        app.runtime.ids.forEach((t => WebExtensions.runtime.sendMessage(t, {
            cmd: "setIcon",
            path: e
        })))
    }
}), Object.defineProperty(app.button, "label", {
    set: function (e) {
        app.runtime.ids.forEach((t => WebExtensions.runtime.sendMessage(t, {
            cmd: "setTitle",
            title: e
        })))
    }
}), Object.defineProperty(app.button, "badge", {
    set: function (e) {
        app.runtime.ids.forEach((t => WebExtensions.runtime.sendMessage(t, {
            cmd: "setBadgeText",
            text: (e || "") + ""
        })))
    }
}), app.tab.open = e => {}, app.platform = function () {
    return `${/Chrome\/[\d\.]*/.exec(navigator.userAgent)[0].replace("Chrome/","Chrome ")} on ${navigator.platform}`
}, app.runtime = function () {
    let e = [];
    return {
        launch: function (e) {
            e()
        },
        suspend: {},
        register: t => {
            e.push(t), e = e.filter(((e, t, n) => n.indexOf(e) === t))
        },
        get ids() {
            return e
        }
    }
}(), app.download = function (e) {
    let t = document.createElement("a");
    t.href = e.url, t.download = e.name, t.style.display = "none", document.body.appendChild(t), t.click()
}, app.sandbox = function (e, t) {
    let n = Promise.defer(),
        i = document.createElement("webview");
    document.body.appendChild(i);
    let r = window.setTimeout(n.reject, t["no-response"], null);
    return i.addEventListener("permissionrequest", (function (e) {
        "download" === e.permission && (window.clearTimeout(r), i && (i.parentNode.removeChild(i), i = null), n.resolve(e.request.url), e.request.deny())
    })), i.src = e, n.promise
};
app = app || require("./firefox/firefox");
(io = "undefined" == typeof exports ? {} : exports).File = function (e) {
    this.root = null, this.file = null, this.name = e.name || "unknown", this.length = e.length, this.path = e.path, this.append = e.append, this.internal = !1, this.writers = 0, this.flushed = null
}, io.File.prototype.open = function () {
    let e = this;
    return app.fileSystem.root.external(this.length, this.path).then((function (t) {
        return e.internal = !1, t
    }), (() => app.fileSystem.root.internal(this.length, this.path).then((function (t) {
        return e.internal = !0, t
    })))).then((function (t) {
        e.root = t;
        let n = e.name,
            i = [].concat.apply([], Object.values(app.mimes)).filter((e => n.endsWith(e))).sort(((e, t) => t.length - e.length))[0] || "";
        if (i) i = "." + i;
        else {
            let e = /\.[^\.]+$/.exec(n);
            e && e.length && (i = e[0])
        }
        return function r(o, s) {
            return o && (n = e.name.replace(i, "") + "-" + o + i), app.fileSystem.file.exists(t, n).then((function (i) {
                return i && !s ? r((o || 0) + 1) : (e.name = n, app.fileSystem.file.create(t, e.name))
            }))
        }(null, e.append)
    })).then((t => e.file = t)).then((() => e.append ? null : app.fileSystem.file.truncate(e.file, e.length))).then((() => e.name))
}, io.File.prototype.write = function (e, t) {
    this.writers += 1;
    let n = this;
    return app.fileSystem.file.write(this.file, e, t).then((function () {
        n.writers -= 1, 0 === n.writers && n.flushed && n.flush()
    }))
}, io.File.prototype.md5 = function () {
    return app.fileSystem.file.md5(this.file, this.length)
}, io.File.prototype.flush = function () {
    let e = this.flushed || app.Promise.defer();
    if (this.writers) this.flushed = e;
    else {
        if (!this.internal) return app.Promise.resolve(); {
            let t = this;
            this.file.file((function (n) {
                let i = document.createElement("a");
                i.download = t.name, i.href = URL.createObjectURL(n), i.dispatchEvent(new MouseEvent("click")), e.resolve(), window.setTimeout((() => t.file.remove((function () {}), (function () {}))), 3e5)
            }), (t => e.reject(t)))
        }
    }
    return e.promise
}, io.File.prototype.launch = function () {
    app.fileSystem.file.launch(this.file).then().catch((e => app.notification(e.message || e)))
}, io.File.prototype.reveal = function () {
    app.fileSystem.file.reveal(this.file).then().catch((e => app.notification(e.message || e)))
}, io.File.prototype.rename = function (e) {
    let t = this;
    return app.fileSystem.file.exists(this.root, e).then((function (n) {
        if (n) throw new Error("a file with the same name already exists");
        return app.fileSystem.file.rename(t.file, t.root, e).then((function (n) {
            return t.name = e, t.file = n, e
        }))
    }))
}, io.File.prototype.remove = function () {
    return app.fileSystem.file.remove(this.file)
}, io.File.prototype.close = function () {
    return app.fileSystem.file.close(this.file)
}, io.File.prototype.toURL = function () {
    return app.fileSystem.file.toURL(this.file)
};
var utils = utils || require("./utils"),
    io = io || require("./io"),
    wget = (app = app || require("./firefox/firefox"), "undefined" == typeof exports ? {} : exports);
const isEdge = navigator.userAgent.includes("Edge"),
    isFirefox = !isEdge && navigator.userAgent.includes("Firefox");
! function () {
    function e(e, t) {
        let n = app.Promise.defer(),
            i = 0,
            r = !1,
            o = app.timer.setTimeout((() => n.reject(new utils.CError("timeout", 3, {
                url: e.urls[0]
            }))), e.timeout),
            s = {
                cancel: function () {}
            };

        function a() {
            return s.read().then((function (r) {
                app.timer.clearTimeout(o), o = app.timer.setTimeout((() => n.reject(new utils.CError("timeout", 3, {
                    url: e.urls[0]
                }))), e.timeout);
                let s = r.value;
                if (s && s.byteLength) {
                    let o = i,
                        l = s.byteLength;
                    return i += l, e.event.emit("progress", {
                        offset: o,
                        length: l
                    }, r.done), e.writer(t, {
                        offset: o,
                        buffer: s
                    }).then((function () {
                        return r.done ? n.resolve("done") : a()
                    }))
                }
                return r.done ? n.resolve("done") : a()
            })).catch((e => n.reject(e)))
        }
        e.event.on("abort", (() => {
            n.reject(new utils.CError("abort", 2))
        }));
        let l = {
            headers: e.headers
        };
        return e.referrer && (l.headers[app.globals.referrer] = e.referrer), app.fetch(e.urls[0], l).then((function (t) {
            if (t.body && (s = t.body.getReader()), r && s.cancel(), !t.ok) throw new utils.CError("fetch error", 4);
            if (t.status && 206 !== t.status && e.headers.Range) throw new utils.CError(`expected 206 but got ${t.status}`, 1, {
                url: e.urls[0]
            });
            return a()
        })).catch((t => n.reject(Object.assign(t, {
            code: 5,
            url: e.urls[0]
        })))), utils.spy(n.promise, (() => {
            r = !0, s.cancel()
        }))
    }
    var t = function (e, n, i) {
        let r = new app.XMLHttpRequest;

        function o() {
            let o = +r.getResponseHeader("Content-Length"),
                s = r.getResponseHeader("Content-Encoding"),
                a = r.getResponseHeader("Length-Computable");
            null !== r.getResponseHeader("Content-Length") || n ? i.resolve({
                length: o,
                encoding: s,
                url: r.responseURL,
                mime: r.getResponseHeader("Content-Type"),
                disposition: r.getResponseHeader("Content-Disposition"),
                "simple-mode": null !== s || "false" === a || 0 === o,
                "multi-thread": !!o && null === s && "bytes" === r.getResponseHeader("Accept-Ranges") && "false" !== a
            }) : t(e, !0, i)
        }
        return i = i || app.Promise.defer(), r.open(n ? "GET" : "HEAD", e.url, !0), r.setRequestHeader("Cache-Control", "max-age=0"), e.referrer && r.setRequestHeader(app.globals.referrer, e.referrer), r.onreadystatechange = function () {
            2 !== r.readyState && 3 !== r.readyState && 4 !== r.readyState || !n || (o(), r.abort())
        }, r.onerror = o, r.onload = o, r.onerror = r.ontimeout = e => i.reject(e), r.timeout = 6e4, r.send(), i.promise
    };

    function n(n, i) {
        n.threads = n.threads || 1, n.retries = n.retries || 30, n.alternatives = (n.alternatives || []).filter((e => e)), n.urls = [];
        let r, o, s, a = new app.EventEmitter,
            l = app.Promise.defer(),
            d = [],
            c = 0,
            u = {},
            p = [];

        function f(e, t) {
            let i = t.offset + e.start,
                r = i + t.buffer.byteLength,
                o = p.filter((e => e.end === i));
            if (o.length) {
                let e = p.indexOf(o[0]);
                if (p[e].end = r, p[e].segments.push(t.buffer), r - p[e].start > n["write-size"]) {
                    let t = p[e];
                    return p.splice(e, 1), u.file.write(t.start, t.segments)
                }
            } else p.push({
                start: i,
                end: r,
                segments: [t.buffer]
            });
            return app.Promise.resolve()
        }

        function g() {
            let e = d.filter((e => "downloading" === e.status)).length;
            return c = e, a.emit("count", e), e
        }

        function m(e) {
            u.status = e || u.status, a.emit("count", 0), "error" === e ? (d.forEach((e => e.event.emit("abort"))), l.reject()) : l.resolve(e), d = []
        }

        function h(e) {
            app.timer.clearTimeout(o), o = app.timer.setTimeout(w, e || n.pause || 500)
        }

        function w() {
            if (-1 !== ["error", "pause", "done"].indexOf(u.status)) return;
            if (0 === u.ranges.length) return m("done");
            let i = u.ranges.filter((e => -1 === u.locks.indexOf(e))).sort(((e, t) => e.start - t.start)),
                o = g();
            i.length && o < n.threads && (! function (n, i) {
                n.urls.push(n.urls.shift());
                let o, s = new app.EventEmitter;
                s.on("progress", (e => b({
                    start: e.offset + i.start,
                    end: e.offset + e.length + i.start - 1
                })));
                let l = {
                    status: "downloading",
                    range: i,
                    event: s,
                    id: "#" + Math.floor(16777215 * Math.random()).toString(16)
                };

                function c() {
                    s.removeAllListeners(), o && a.emit("progress", l, o)
                }

                function p(e) {
                    let t = n.urls.indexOf(e); - 1 !== t && (n.urls.splice(t, 1), a.emit("add-log", `${e} is removed from url list due to a fetch error`, {
                        type: "warning"
                    }))
                }
                d.push(l), g(), s.on("progress", (function (e) {
                        let t = parseInt((e.offset + e.length) / r.length * 100);
                        (isNaN(m) || t > m || 100 === t) && (a.emit("progress", l, e), m = t), a.emit("progress-for-speed", l, e), o = e
                    })),
                    function (t, n, i, r, o) {
                        return t = Object.assign({
                            headers: {},
                            event: i,
                            writer: o
                        }, t), r && (t.headers.Range = `bytes=${n.start}-${n.end}`), e(t, n)
                    }(n, i, s, 0 !== i.start || i.end !== r.length - 1 && i.end !== 1 / 0, f).then((function (e) {
                        r["simple-mode"] && "done" === e && (u.ranges = [], u.locks = []), l.status = e, c(), h(n["short-pause"] || 100)
                    }), (function (e) {
                        if (l.status = "error", a.emit("add-log", `fetch error[${e.code}]; "${e.message}"`, {
                                type: "warning"
                            }), c(), "abort" === e.message || 2 === e.code) u.locks = u.locks.filter((e => e.start < i.start || e.end > i.end));
                        else {
                            if (!(u.retries < n.retries && r["multi-thread"])) return a.emit("pause");
                            u.locks.filter((e => e.start === i.start)).length && (u.retries += 1), u.locks = u.locks.filter((e => e.start < i.start || e.end > i.end)), n.urls.length > 1 && e.url && 1 !== e.code ? t({
                                url: e.url,
                                referrer: n.referrer
                            }).then((function (t) {
                                t.length !== r.length && p(e.url)
                            }), (() => p(e.url))).then(h) : n.urls.length > 1 && e.url && 1 === e.code ? (p(e.url), h()) : 1 === n.urls.length && 1 === e.code ? 0 === i.start ? (d.forEach((e => e.event.emit("abort"))), n.threads = 1, u.locks = [], u.ranges = [{
                                start: 0,
                                end: r.length - 1
                            }], r["multi-thread"] = !1, a.emit("info", r), a.emit("add-log", "resuming with one thread", {
                                type: "warning"
                            }), h()) : h(4 * (n.pause || 500)) : h()
                        }
                    }));
                var m
            }(n, i[0]), u.locks.push(i[0]), o < n.threads && h())
        }

        function b(e) {
            let t = u.ranges.filter((t => t.start <= e.start && t.end >= e.end));
            if (1 !== t.length) return a.emit("add-log", "Internal Error: `internals.ranges.length` is not equal to one", {
                type: "error"
            }), m("error");
            if (t[0].start < e.start) return a.emit("add-log", "Internal Error: `rngs[0].start` is not euqal to range.start", {
                type: "error"
            }), m("error");
            var n;
            t[0].end > e.end && (n = {
                start: e.end + 1,
                end: t[0].end
            }, u.ranges.push(n), u.locks.push(n)), u.ranges.splice(u.ranges.indexOf(t[0]), 1), u.locks.splice(u.locks.indexOf(t[0]), 1);
            let i = u.ranges.reduce(((e, t) => e + (t.end - t.start)), 0),
                o = parseInt((r.length - i) / r.length * 100);
            (isNaN(b.percent) || b.percent < o) && a.emit("percent", u.ranges.reduce(((e, t) => e + (t.end - t.start)), 0), r.length), b.percent = o
        }
        return utils.assign(u, "status", a).assign(u, "retries", a, 0), a.on("status", (e => a.emit("add-log", `Download status is changed to **${e}**`))), i ? (r = i.info, u.status = "pause", a.emit("info", r)) : u.status = "head", a.on("call-schedule", h), a.on("info", (function () {
            0 === r.length && a.emit("add-log", "`info.length` is equal to zero", {
                type: "warning"
            }), r.encoding && a.emit("add-log", "`info.encoding` is not null", {
                type: "warning"
            }), i ? (u.ranges = i.internals.ranges, u.locks = [], u.status = "pause", u.name = i.file.name) : (! function (e) {
                e = Math.max(e, n["min-segment-size"] || 51200), e = Math.min(e, n["max-segment-size"] || 104857600), e = Math.min(r.length, e);
                let t = Math.floor(r.length / e);
                r["multi-thread"] || (t = 1);
                let i = Array.from(new Array(t), ((e, t) => t));
                u.ranges = i.map(((t, n, i) => ({
                    start: t * e,
                    end: i.length === n + 1 ? r.length - 1 : (t + 1) * e - 1
                }))), u.locks = []
            }(Math.floor(r.length / n.threads)), r["simple-mode"] && (u.ranges[0].end = 1 / 0, a.emit("add-log", "Server does not support multi-threading; Either file-size is not defined or file is encoded", {
                type: "warning"
            })), u.status = "download", u.name = function (e) {
                let t = e.urls[0],
                    n = e.name,
                    i = (e.mime || "").split(";").shift(),
                    r = e.disposition;
                if (!n && r) {
                    let e = /filename\=([^\;]*)/.exec(r);
                    e && e.length && (n = e[1].replace(/[\"\']$/, "").replace(/^[\"\']/, ""))
                }
                if (!n) {
                    t = t.replace(/\/$/, "");
                    let e = /(title|filename)\=([^\&]+)/.exec(t);
                    n = e && e.length ? e[2] : t.substring(t.lastIndexOf("/") + 1), n = decodeURIComponent(n.split("?")[0].split("&")[0]) || "unknown"
                }
                let o = /\.\w{2,}$/.exec(n);
                if (o && o.length && (n = n.replace(o[0], "")), n = n.replace(/[\\\/\:\*\?\"<\>\|\"]/g, "-"), n = n.trim(), o && o.length) return n + o[0];
                let s = app.mimes[i] || "";
                if (s) {
                    let e = new RegExp(".(" + s.join("|") + ")$");
                    return n = n.replace(e, ""), n + "." + s[0]
                }
                return n
            }(Object.assign({
                mime: r.mime,
                disposition: r.disposition
            }, n))), a.emit("mime", r.mime), u.file = new io.File({
                name: u.name,
                mime: r.mime,
                path: n.folder,
                length: r.length,
                append: !!i
            }), a.emit("name", "Allocating space ..."), u.file.open().then((function (e) {
                function o() {
                    return Promise.all(n.alternatives.map((e => t({
                        url: e,
                        referrer: n.referrer
                    }).catch((() => null))))).then((e => e.filter((e => e)))).then((e => e.filter((e => (e.length === r.length ? a.emit("add-log", `${e.url} is added as a mirror`) : a.emit("add-log", `Cannot use ${e.url} as a mirror. Server returns **${e.length}** bytes for file-size`, {
                        type: "warning"
                    }), e.length === r.length))))).then((e => e.map((e => e.url)))).then((e => {
                        n.urls = n.urls.concat(e)
                    }))
                }
                if (a.emit("name", u.name), e && e !== u.name && (u.name = e, a.emit("name", u.name), n["pause-on-exists"] ? (a.emit("add-log", "File with the same name already exists. Pausing the download for user attention.", {
                        type: "warning"
                    }), app.notification("You new download is paused as a file with the same name exists. Resume if needed."), n["persistent-pause"] = !0) : a.emit("add-log", 'File with the same name already exists. Still downloading due to "pause-on-exists" argument.', {
                        type: "warning"
                    })), i) a.emit("add-log", "This job is restored from session manager"), a.emit("pause");
                else if (n["temporary-pause"] || n["persistent-pause"]) a.emit("pause"), u.ranges.length > 1 && o(), 1 === u.ranges.length && n.alternatives.length && a.emit("add-log", "I am not going to validate mirrors as this download is single threaded", {
                    type: "warning"
                });
                else if (1 !== u.ranges.length && n.alternatives.length) {
                    let e = n.threads;
                    n.threads = 1, w(), o().then((function () {
                        n.threads = e, w()
                    }))
                } else w(), n.alternatives.length && a.emit("add-log", "I am not going to validate mirrors as this download is single threaded", {
                    type: "warning"
                })
            })).catch((e => {
                a.emit("add-log", `Cannot open file; ${e.message||e}`, {
                    type: "error"
                }), m("error")
            }))
        })), a.on("pause", (function (e) {
            e && (n["persistent-pause"] = !0), u.status = "pause", d.forEach((e => e.event.emit("abort"))), g(), app.Promise.all(p.map((e => u.file.write(e.start, e.segments)))).catch((e => {
                a.emit("add-log", `Cannot open file; ${e.message||e}`, {
                    type: "error"
                }), m("error")
            }))
        })), a.on("resume", (function () {
            "pause" === u.status && (u.retries = 0, u.locks.length && (u.locks = []), u.status = "download", n.urls.push(n.url), n.urls = n.urls.filter(((e, t, n) => n.indexOf(e) === t)), w())
        })), a.on("cancel", (() => m("error"))), a.on("error", (function () {
            "error" !== u.status && m("error")
        })), a.on("rename", (function (e) {
            (e = e.trim()) && u.name !== e && u.file.rename(e).then((() => {
                u.name = e, a.emit("name", u.name), a.emit("log", `File-name is changed to ${u.name}`)
            }), (e => {
                a.emit("add-log", `**Unsuccesful** renaming; ${e.message}`, {
                    type: "warning"
                }), app.notification(e.message)
            }))
        })), a.on("info", (() => {
            a.emit("add-log", `File mime type is **${r.mime}**`), a.emit("add-log", `File encoding is **${r.encoding}**`), a.emit("add-log", `Server multi-threading support status is **${r["multi-thread"]}**`), a.emit("add-log", `File length in bytes is **${r.length}**`), a.emit("add-log", `Actual downloadable URL is ${n.urls[0]}`)
        })), new app.Promise((function (e) {
            if (n["use-native"]) return a.emit("add-log", "waiting for native-method to catch download link ..."), app.sandbox(n.url, {
                referrer: n.referrer,
                "no-response": 4e4
            }).then((function (t) {
                a.emit("add-log", `native-method returned ${t}`), n.url = t, e()
            })).catch((function () {
                a.emit("add-log", "native-method is not responding; timeout", {
                    type: "warning"
                }), e()
            }));
            e()
        })).then((() => app.Promise.race([n.url, n.url, n.url].map((e => t({
            url: e,
            referrer: n.referrer
        })))))).then((function (e) {
            r = e, n.urls = [r && r.url ? r.url : n.url], a.emit("info", r)
        }), (e => {
            a.emit("add-log", `Cannot get file information form server; ${e.message}`, {
                type: "error"
            }), m("error")
        })), s = utils.spy(l.promise, (function () {
            return app.Promise.all(p.map((e => u.file.write(e.start, e.segments)))).then((() => p = [])).then((function () {
                return r.length > (n["max-size-md5"] || 524288e3) ? "MD5 calculation is skipped" : u.file.md5()
            })).then((function (e) {
                return u.md5 = e, a.emit("md5", e), a.emit("add-log", `MD5 checksum is **${e}**`), u.status
            }))
        })), s = utils.spy(s, (function () {
            return u.file.close().then().catch((function () {}))
        })), {
            event: a,
            promise: s,
            resolve: l.resolve,
            reject: l.reject,
            get segments() {
                return d
            },
            get threads() {
                return c
            },
            get status() {
                return u.status
            },
            get retries() {
                return u.retries
            },
            get info() {
                return r
            },
            get internals() {
                return u
            },
            isAvailable: () => !n["persistent-pause"],
            modify: function (e) {
                n.threads = e.threads || n.threads, n.timeout = e.timeout ? 1e3 * e.timeout : n.timeout, e.name !== u.name && a.emit("rename", e.name.replace(/[\\\/\:\*\?\"<\>\|\"]/g, "-"))
            }
        }
    }

    function i(e, t) {
        let i, r = function (e, t) {
                return n(e, t)
            }(e, t),
            o = [0],
            s = !1;

        function a() {
            app.timer.clearInterval(i), d()
        }

        function l() {
            return o.reduce(((e, t) => e + t), 0) / o.length / e.update * 1e3
        }

        function d() {
            r.event.emit("speed", l()), o.push(0), o = o.slice(-5), 0 === o.filter((e => e)).length ? "download" === r.internals.status && s && (s = !1, r.event.emit("add-log", "Server seems to be done", {
                type: "warning"
            }), app.timer.setTimeout((function () {
                0 === o.filter((e => e)).length && "download" === r.internals.status && (r.event.emit("call-schedule"), r.event.emit("add-log", "Requesting a new thread", {
                    type: "warning"
                }))
            }), e.timeout)) : s = !0
        }

        function c() {
            app.timer.clearInterval(i), i = app.timer.setInterval(d, e.update)
        }
        return e.update = e.update || 1e3, r.event.on("progress-for-speed", (function (e, t) {
            o[o.length - 1] += t.length
        })), r.event.on("pause", (function () {
            o = [0], a()
        })), r.event.on("resume", c), t || c(), r.promise = utils.spy(r.promise, a), Object.defineProperty(r, "speed", {
            get: function () {
                return l()
            }
        }), r
    }
    wget.download = function (e, t) {
        let n = i(e, t);
        return n.promise = utils.spy(n.promise, (function () {
            app.timer.setTimeout((() => n.event.removeAllListeners()), 5e3)
        })), n
    }
}();
app = app || require("./firefox/firefox");
var config = config || require("./config"),
    icon = "undefined" == typeof exports ? {} : exports;
! function () {
    var e, t, n, i = app.canvas();

    function r(e, t, n) {
        var r = i.getContext("2d");
        return i.width = 38 * t, i.height = 38 * t, r.clearRect(0, 0, 38 * t, 38 * t), r.beginPath(), r.arc(19 * t, 19 * t, 17 * t, 0, 2 * Math.PI), r.strokeStyle = "#a2a2a2", r.lineWidth = 4 * t, r.stroke(), r.beginPath(), r.arc(19 * t, 19 * t, 17 * t, 0, e / 100 * 2 * Math.PI), r.strokeStyle = "#2883fc", r.lineWidth = 4 * t, r.stroke(), "error" === n ? (r.beginPath(), r.moveTo(28 * t, 26 * t), r.lineTo(19 * t, 8 * t), r.lineTo(10 * t, 26 * t), r.closePath(), r.strokeStyle = "#fff", r.fillStyle = "#595959", r.lineWidth = 2 * t, r.fill(), r.beginPath(), r.moveTo(19 * t, 21 * t), r.lineTo(19 * t, 14 * t), r.stroke(), r.beginPath(), r.arc(19 * t, 23 * t, 1 * t, 0, 2 * Math.PI), r.fillStyle = "#fff", r.fill()) : "done" === n ? (r.beginPath(), r.moveTo(19 * t, 28 * t), r.lineTo(12 * t, 22 * t), r.lineTo(15 * t, 18 * t), r.lineTo(18 * t, 22 * t), r.lineTo(25 * t, 10 * t), r.lineTo(28 * t, 12 * t), r.closePath(), r.fillStyle = "#595959", r.fill()) : (r.beginPath(), r.moveTo(16 * t, 10 * t), r.lineTo(22 * t, 10 * t), r.lineTo(22 * t, 22 * t), r.lineTo(26 * t, 22 * t), r.lineTo(19 * t, 30 * t), r.lineTo(12 * t, 22 * t), r.lineTo(16 * t, 22 * t), r.lineTo(16 * t, 10 * t), r.fillStyle = "#595959", r.fill()), i.toDataURL("image/png")
    }

    function o(e, t, n) {
        var r = i.getContext("2d");
        return i.width = 36 * t, i.height = 36 * t, r.clearRect(0, 0, 36 * t, 36 * t), r.beginPath(), r.arc(18 * t, 18 * t, 16 * t, 0, 2 * Math.PI), r.strokeStyle = "#a2a2a2", r.lineWidth = 4 * t, r.stroke(), r.beginPath(), r.arc(18 * t, 18 * t, 16 * t, 0, e / 100 * 2 * Math.PI), r.strokeStyle = "#2883fc", r.lineWidth = 4 * t, r.stroke(), "error" === n ? (r.beginPath(), r.moveTo(27 * t, 26 * t), r.lineTo(18 * t, 7 * t), r.lineTo(9 * t, 26 * t), r.closePath(), r.strokeStyle = "#fff", r.fillStyle = "#595959", r.lineWidth = 2 * t, r.fill(), r.beginPath(), r.moveTo(18 * t, 21 * t), r.lineTo(18 * t, 14 * t), r.stroke(), r.beginPath(), r.arc(18 * t, 23 * t, 1 * t, 0, 2 * Math.PI), r.fillStyle = "#fff", r.fill()) : "done" === n ? (r.beginPath(), r.moveTo(18 * t, 28 * t), r.lineTo(9 * t, 22 * t), r.lineTo(14 * t, 18 * t), r.lineTo(17 * t, 22 * t), r.lineTo(25 * t, 10 * t), r.lineTo(28 * t, 12 * t), r.closePath(), r.fillStyle = "#595959", r.fill()) : (r.beginPath(), r.moveTo(14 * t, 10 * t), r.lineTo(22 * t, 10 * t), r.lineTo(22 * t, 20 * t), r.lineTo(26 * t, 20 * t), r.lineTo(18 * t, 28 * t), r.lineTo(10 * t, 20 * t), r.lineTo(14 * t, 20 * t), r.lineTo(14 * t, 10 * t), r.fillStyle = "#595959", r.fill()), i.toDataURL("image/png")
    }
    icon.register = () => i = app.canvas(), icon.percent = function (s, a, l) {
        i && ("done" !== s && "error" !== s && (s = "normal"), a = 100 === (a = null === a ? e : a) ? 0 : a, "normal" !== s && (app.timer.clearTimeout(n), n = app.timer.setTimeout(icon.percent, 1e3 * config.icon.timeout, null, "normal", !0), t = s), l && (n = null), "normal" === s && n && (s = t), e = a, app.button.icon = "firefox" === app.globals.browser ? {
            18: o(a, .5, s),
            36: o(a, 1, s),
            72: o(a, 2, s)
        } : {
            19: r(a, .5, s),
            38: r(a, 1, s)
        })
    }
}();
app = app || require("./firefox/firefox"), config = config || require("./config");
var session = "undefined" == typeof exports ? {} : exports;
app.on("session:error", (e => {
    app.notification(e.message || e)
})), app.on("session:warning", (function () {})), Object.defineProperty(session, "db", function () {
    let e = {
        dummy: !0,
        error: () => app.Promise.reject(new Error("session is not yet initialized")),
        inprogress: {
            get clear() {
                return session.db.error
            },
            get toArray() {
                return session.db.error
            },
            get where() {
                return session.db.error
            }
        },
        get failed() {
            return session.db.inprogress
        },
        get completed() {
            return session.db.inprogress
        },
        get delete() {
            return session.db.inprogress
        }
    };
    return {
        enumerable: !0,
        configurable: !0,
        get: () => e,
        set: t => e = t
    }
}()), session.init = () => {
    app.crequire("Dexie", ["dexie"], {
        global: {},
        setTimeout: app.timer.setTimeout,
        clearTimeout: app.timer.clearTimeout
    }, (function (e) {
        let t = e.Dexie;
        return t.dependencies.indexedDB = app.indexedDB, t.dependencies.IDBKeyRange = app.IDBKeyRange, t
    })).then((e => {
        session.db = new e(config.session.name + "-" + config.session.id), session.db.version(config.session.version).stores({
            completed: "++id, date, urls, name, path, size, encoding, mime, threading",
            inprogress: "++id, date, info, obj, internals, file, segments",
            failed: "++id, date, urls, name, size, error"
        }), session.db.open().then((() => session.db.inprogress.toArray())).then((e => {
            app.emit("session:load", e), app.Promise.all([session.kill.days.failed(config.session.expire.failed), session.kill.days.completed(config.session.expire.completed)]).catch((e => {}))
        })).catch((e => app.emit("session:error", e)))
    })).catch((e => app.emit("session:error", e)))
}, session.list = {
    inprogress: () => session.db.inprogress.toArray(),
    failed: () => session.db.failed.toArray(),
    completed: () => session.db.completed.toArray()
}, session.kill = function () {
    function e(e) {
        return new Date((new Date).getTime() - 24 * (e || 0) * 60 * 60 * 1e3)
    }
    return {
        delete: () => session.db.delete(),
        all: {
            failed: () => session.db.failed.clear(),
            completed: () => session.db.completed.clear()
        },
        days: {
            failed: t => session.db.failed.where("date").below(e(t)).delete(),
            completed: t => session.db.completed.where("date").below(e(t)).delete()
        },
        id: {
            failed: e => session.db.failed.where("id").equals(e).delete(),
            completed: e => session.db.completed.where("id").equals(e).delete()
        }
    }
}(), session.assign = function (e) {
    e.session || session.db.inprogress.add({
        date: new Date,
        info: e.info,
        stats: e.stats,
        obj: e.obj,
        internals: {
            ranges: e.internals.ranges
        },
        file: {
            name: e.internals.file.name,
            path: e.internals.file.path
        },
        segments: {}
    }).then((t => e.session = t)).catch((e => app.emit("session:error", e)))
}, session.register = function (e) {
    session.db.dummy || (e.info ? session.assign(e) : e.event.once("info", (() => session.assign(e))), e.event.on("name", (() => {
        e.session ? session.db.inprogress.where("id").equals(e.session).modify((t => {
            t.file.name = e.internals.file.name
        }), (e => app.emit("session:error", e))) : app.emit("session:warning", "wget.session is not yet created")
    })), e.event.on("status", (t => {
        "done" !== t && "error" !== t || (e.session ? (session.db.inprogress.where("id").equals(e.session).delete().catch((e => app.emit("session:error", e))), session.db["done" === t ? "completed" : "failed"].add({
            date: new Date,
            urls: e.obj.urls,
            name: e.internals.file.name,
            path: e.internals.file.path || e.internals.file.root.path,
            size: e.info.length,
            encoding: e.info.encoding,
            mime: e.info.mime,
            threading: e.info["multi-thread"]
        }).catch((e => app.emit("session:error", e)))) : app.emit("session:warning", "wget.session is not yet created")), "pause" === t && (e.session ? session.db.inprogress.where("id").equals(e.session).modify((t => (t.internals.ranges = e.internals.ranges, t.stats = e.stats, t))).catch((e => app.emit("session:error", e))) : app.emit("session:warning", "wget.session is not yet created"))
    })))
};
app = app || require("./firefox/firefox"), wget = wget || require("./wget"), config = config || require("./config"), utils = utils || require("./utils"), icon = icon || require("./icon");
var mwget = "undefined" == typeof exports ? {} : exports;
Object.filter = (e, t) => Object.keys(e).filter((n => t(e[n]))).reduce(((t, n) => (t[n] = e[n], t)), {}), Object.size = function (e) {
        var t, n = 0;
        for (t in e) e.hasOwnProperty(t) && n++;
        return n
    },
    function () {
        let e = {},
            t = {
                add: [],
                done: [],
                progress: [],
                count: [],
                details: [],
                percent: [],
                "total-percent": [],
                speed: [],
                logs: []
            },
            n = !1;

        function i() {
            const i = Object.filter(e, (e => "download" === e.status || "head" === e.status));
            let r = Object.size(i);
            return t.count.forEach((e => e(r))), r && !n && (n = !0), !r && n && (n = !1), app.button.badge = r || "", r
        }
        let r = utils.debounce((function (n) {
            let i, r;
            ! function (e) {
                i = Object.values(e).reduce(((e, t) => e + t.info.length), 0), r = Object.values(e).reduce(((e, t) => e + (t.remained || t.info.length)), 0)
            }(Object.filter(e, (e => "download" === e.status || "pause" === e.status)));
            let o = (i - r) / i * 100;
            0 === r && (o = 0), 0 === i && (o = 100), icon.percent(n, o), t["total-percent"].forEach((e => e(o)))
        }), 1e3 * config.mwget.percent["rate-total"]);
        mwget.download = function (n, o) {
            if (utils.validate(n.url)) {
                let s = wget.download(n, o);
                s.stats = o ? o.stats : {}, o && (s.remained = o.internals.ranges.reduce(((e, t) => e + (t.end - t.start)), 0)), s.log = function () {
                    let e = [];
                    return {
                        push: function (t, n) {
                            let i = {
                                log: t,
                                properties: n,
                                date: (new Date).toLocaleTimeString()
                            };
                            e.push(i), s.event.emit("log", i)
                        },
                        get: function () {
                            return e
                        }
                    }
                }();
                let a = n.tabId;
                return e[a] = s, s.obj = n, s.promise.then((function (e) {
                    let n = "done" === e ? s.internals.md5 : "";
                    t.done.forEach((t => t(a, e, n))), s.stats = {}
                })).catch((e => {
                    s.log.push(`Internal Error; ${e?e.message||e.exception||e:"no error message"}`, {
                        type: "error"
                    }), t.done.forEach((e => e(a, "error", ""))), s.stats = {}
                })), s.log.push(`Downloading ${n.url}`), s.log.push(`Referrer page is ${n.referrer}`), s.event.on("progress", (function (e, n) {
                    let i = e.range.start,
                        r = n.offset + n.length,
                        o = s.info.length,
                        l = {
                            id: e.id,
                            start: i / o,
                            width: r / o
                        };
                    s.stats[l.id] = l, t.progress.forEach((e => e(a, l)))
                })), s.event.on("log", (e => t.logs.forEach((t => t(a, e))))), s.event.on("name", (e => t.details.forEach((t => t(a, "name", e))))), s.event.on("mime", (e => t.details.forEach((t => t(a, "mime", e))))), s.event.on("status", (function (e) {
                    t.details.forEach((t => t(a, "status", e))), "pause" !== e || s.info["multi-thread"] || 0 === s.threads || (s.event.emit("cancel"), s.log.push("Download status changed to paused while this download is not supporting multi-threading.", {
                        type: "error"
                    })), app.timer.setTimeout(i, 500), r.now(e)
                })), s.event.on("count", (e => t.details.forEach((t => t(a, "count", e))))), s.event.on("retries", (e => t.details.forEach((t => t(a, "retries", e))))), s.event.on("info", (e => t.details.forEach((t => t(a, "info", e))))), s.event.on("add-log", ((e, t) => s.log.push(e, t))), s.event.on("speed", (e => t.speed.forEach((t => t(a, e, s.remained))))), s.event.on("percent", (function (e, n) {
                    s.remained = e, t.percent.forEach((t => t(a, e, n))), r()
                })), o || t.add.forEach((e => e(a))), app.timer.setTimeout(i, 0), a
            }
            return app.notification(`URL is not valid; ${n.url}`)
        }, mwget.list = () => e, mwget.get = t => e[t], mwget.id = e => e.tabId, mwget.count = () => i(), mwget.log = t => e[t].log.get(), mwget.stats = function (t) {
            let n = e[t];
            if (n) return n.stats
        }, mwget.pause = function (t, n) {
            let i = e[t];
            i && i.event.emit("pause", n)
        }, mwget.resume = function (t) {
            let n = e[t];
            n && n.event.emit("resume")
        }, mwget.cancel = function (t) {
            let n = e[t];
            n && n.event.emit("cancel")
        }, mwget.remove = function (t) {
            let n = e[t];
            if (n) {
                if ("download" === n.status) throw Error("Cannot remove an instance while it is active. Try to pause the download first");
                "pause" !== n.status && "error" !== n.status || n.internals.file && n.internals.file.remove().catch((function () {})), delete e[t], app.manager.send("remove", t)
            }
        }, mwget.addEventListener = function (e, n) {
            for (let i in t) i === e && t[e].push(n)
        }, mwget.removeEventListener = function (e, n) {
            for (let i in t)
                if (i === e) {
                    let i = t[e].indexOf(n);
                    i && t[e].splice(i, 1)
                }
        }
    }();
app = app || require("./firefox/firefox"), config = config || require("./config"), mwget = mwget || require("./mwget"), utils = utils || require("./utils");
app.button.onCommand((function () {
    app.tab.list().then((function (e) {
        (e = e.filter((e => e && 0 === e.url.indexOf(app.getURL("manager/index.html"))))).length ? app.tab.activate(e[0]) : app.tab.open(app.getURL("./manager/index.html"))
    }))
}));
var actions = {
    download: function (e) {
        e.threads = e.threads || config.wget.threads, e.timeout = 1e3 * e.timeout || 1e3 * config.wget.timeout, e.update = 1e3 * e.update || 1e3 * config.wget.update, e.pause = e.pause || config.wget.pause, e["short-pause"] = e["short-pause"] || config.wget["short-pause"], e["use-native"] = e["use-native"] || !1, e["write-size"] = e["write-size"] || config.wget["write-size"], e["max-size-md5"] = e["max-size-md5"] || config.wget["max-size-md5"], e.retries = e.retries || config.wget.retries, e.folder = e.folder || config.wget.directory, e["min-segment-size"] = e["min-segment-size"] || config.wget["min-segment-size"], e["max-segment-size"] = e["max-segment-size"] || config.wget["max-segment-size"], e["pause-on-exists"] = e["pause-on-exists"] || config.wget["pause-on-exists"], e["temporary-pause"] = e["temporary-pause"] || config.triggers.pause.enabled && mwget.count() >= config.triggers.pause.value, !e.folder && config.wget["notice-download"] && app.globals.folder && (app.notification("Saving in the default download directory. Add a new job from manager to change the directory."), config.wget["notice-download"] = !1), mwget.download(e)
    }
};
actions.open = {
        logs: () => app.manager.send("logs"),
        job: e => app.manager.send("job", e)
    },
    function (e) {
        actions.download = function (t) {
            let n = t.url;
            "string" == typeof n && (n = n.replace(/\s*\,\s*http/g, String.fromCharCode(0) + "http").split(String.fromCharCode(0))), n = [].concat.apply([], n.map((e => {
                if (/\{\d+\.\.\d+\}/.test(e)) {
                    let t = /\{(\d+)\.\.(\d+)\}/.exec(e),
                        n = +t[1],
                        i = +t[2];
                    return Array(i - n + 1).fill().map(((e, t) => t + n)).map((n => e.replace(t[0], n)))
                }
                return e
            }))), n = n.map((e => e.startsWith("https://www.google.") && -1 !== e.indexOf("&url=") ? decodeURIComponent(e.split("&url=")[1].split("&")[0]) : e)), n.length > 1 && (t.alternatives = [], t.name = ""), n.map((e => Object.assign({}, t, {
                url: e
            }))).forEach(e)
        }
    }(actions.download), app.on("open", (function (e) {
        e in actions.open && actions.open[e]()
    })), app.on("download", actions.download),
    function (e) {
        "opera" !== app.globals.browser && e.push(["Bypass page redirection then download", e => actions.download(Object.assign(e, {
            "use-native": !0
        }))], ["Bypass page redirection then pause", e => actions.download(Object.assign(e, {
            "use-native": !0,
            "persistent-pause": !0
        }))]), app.menu.bind(app, "Turbo Download Manager").apply(app, e)
    }([
        ["Download now", actions.download],
        ["Download later", e => actions.download(Object.assign(e, {
            "persistent-pause": !0
        }))]
    ]), mwget.addEventListener("done", ((e, t) => app.manager.sendTab("status", {
        id: e,
        status: t
    }))), mwget.addEventListener("add", (e => app.manager.sendTab("new", {
        id: e
    }))), mwget.addEventListener("details", (function (e, t, n) {
        if ("name" === t && app.manager.sendTab("name", {
                id: e,
                name: n
            }), "mime" === t && app.manager.sendTab("mime", {
                id: e,
                mime: n
            }), "status" === t) {
            var i = "";
            "pause" == n && (i = {
                "temporary-pause": mwget.get(e).obj["temporary-pause"]
            }), app.manager.sendTab("status", {
                id: e,
                status: n,
                extraStatus: i
            }), app.info.sendTab("status", {
                id: e,
                status: n
            })
        }
        "status" === t && "done" === n && config.triggers.success.enabled && app.timer.setTimeout(mwget.remove, 60 * config.triggers.success.value * 1e3, e), "status" === t && "error" === n && config.triggers.fail.enabled && app.timer.setTimeout(mwget.remove, 60 * config.triggers.fail.value * 1e3, e), "status" === t && "done" === n && config.triggers["play-single"].enabled, "status" === t && "done" === n && config.triggers["play-combined"].enabled && !config.triggers["play-single"].enabled && mwget.count(), "count" === t && app.manager.sendTab("count", {
            id: e,
            count: n
        }), "info" === t && (app.manager.sendTab("size", {
            id: e,
            size: n.length
        }), app.manager.sendTab("chunkable", {
            id: e,
            chunkable: n["multi-thread"]
        })), "retries" === t && app.manager.sendTab("retries", {
            id: e,
            retries: n
        })
    })), mwget.addEventListener("percent", (function (e, t, n) {
        let i = (n - t) / n * 100;
        app.manager.sendTab("percent", {
            id: e,
            percent: i
        })
    })), mwget.addEventListener("total-percent", (e => app.manager.send("total-percent", e))), mwget.addEventListener("speed", ((e, t, n) => {
        app.manager.sendTab("speed", {
            id: e,
            speed: t,
            time: n / t
        })
    })), mwget.addEventListener("progress", ((e, t) => app.manager.sendTab("progress", {
        id: e,
        stat: t
    }))), mwget.addEventListener("logs", ((e, t) => app.info.send("log", {
        id: e,
        log: [t]
    }))), app.manager.receive("init", (function () {
        const e = mwget.get(this.id);
        e && app.manager.sendTab("add", {
            id: this.id,
            name: e.internals.name,
            mime: e.info ? e.info.mime : "",
            size: e.info ? e.info.length : 0,
            percent: e.info ? (e.info.length - e.remained) / e.info.length * 100 : 0,
            chunkable: !!e.info && e.info["multi-thread"],
            stats: mwget.stats(this.id),
            status: e.status,
            speed: e.speed,
            threads: e.threads,
            retries: e.retries
        })
    })), app.manager.terminateTask = function (e) {
        mwget.get(e) && (mwget.pause(e), mwget.cancel(e), mwget.remove(e))
    }, app.manager.receive("cmd", (function (e) {
        if ("setDirectlySave" === e.cmd && localStorage.setItem("setDirectlySave", !0), "pause" === e.cmd && mwget.pause(e.id, !0), "resume" === e.cmd && mwget.resume(e.id), "trash" === e.cmd && mwget.remove(e.id), "cancel" === e.cmd && mwget.cancel(e.id), "info" === e.cmd && app.manager.sendTab("info", e), "modify" === e.cmd && app.manager.sendTab("modify", e), "native" === e.cmd) {
            let t = mwget.get(e.id);
            app.download({
                url: t.info ? t.info.url : t.obj.url,
                name: t.internals.name,
                path: t.obj.folder
            })
        }
        if ("use-native" === e.cmd) {
            let t = mwget.get(e.id);
            actions.download(Object.assign(t.obj, {
                "use-native": !0
            }))
        }
        if (e.cmd, "reveal" === e.cmd) {
            let t = mwget.get(e.id);
            if (app.globals.reveal) return t.internals.file.reveal();
            app.notification("Opening container folder is not supported in this platform")
        }
        if ("download" === e.cmd && actions.download(e), "flushfile" === e.cmd) {
            mwget.get(e.id).internals.file.flush().then((() => {
                app.manager.sendTab("willDelFile", {
                    id: e.id
                })
            })).catch((t => {
                app.manager.sendTab("bgError", {
                    id: e.id,
                    errMsg: t.toString()
                })
            }))
        }
        if ("save2gdrive" === e.cmd) {
            mwget.get(e.id).internals.file.file.file((t => {
                let n = document.createElement("a");
                n.href = URL.createObjectURL(t), app.manager.sendTab("save2driveData", {
                    id: e.id,
                    fileDataURL: n.href
                })
            }), (t => {
                app.manager.sendTab("bgError", {
                    id: e.id,
                    errMsg: t.toString()
                })
            }))
        }
    })), app.manager.receive("open", app.emit.bind(app, "open")), app.add.receive("download", (function (e) {
        app.manager.sendTab("hide", {
            id: e.id
        }), e.threads && (config.wget.threads = e.threads), e.timeout && (config.wget.timeout = e.timeout), e.tabId = parseInt(this.id), actions.download(e)
    })), app.add.receive("cmd", (function (e) {
        e.cmd, "empty" === e.cmd && (config.wget.directory = "")
    })), app.add.receive("init", (function () {
        app.OS.clipboard.get().then((function (e) {
            let t = e.split(/\s*\,\s*/).map(utils.validate).reduce(((e, t) => e && t), !0);
            app.add.send("init", {
                settings: {
                    threads: config.wget.threads,
                    timeout: config.wget.timeout,
                    folder: config.wget.directory
                },
                clipboard: t ? e : ""
            })
        }))
    })), app.add.receive("no-folder", (() => app.notification('Please select the destination folder using the "browse" button'))), app.info.receive("init", (function (e) {
        app.info.sendTab("log", {
            id: e,
            log: mwget.log(e)
        }), app.info.sendTab("status", {
            id: e,
            status: mwget.get(e).status
        })
    })), app.info.receive("cmd", (function (e) {
        "folder" === e.cmd && mwget.get(e.id).internals.file.reveal(), "file" === e.cmd && mwget.get(e.id).internals.file.launch(), "remove" === e.cmd && (app.manager.sendTab("hide", {
            id: e.id
        }), mwget.remove(e.id))
    })), app.info.receive("open", app.tab.open), app.modify.receive("init", (function (e) {
        let t = mwget.get(e);
        t && app.modify.sendTab("init", {
            id: e,
            name: t.internals.name,
            threads: t.obj.threads,
            timeout: t.obj.timeout / 1e3
        })
    })), app.modify.receive("modified", (function (e) {
        app.manager.sendTab("hide", {
            id: e.id
        });
        let t = mwget.get(e.id);
        t && t.modify(e)
    })), app.triggers.receive("init", (function () {
        app.triggers.send("init", {
            pause: {
                enabled: config.triggers.pause.enabled,
                value: config.triggers.pause.value
            },
            start: {
                enabled: config.triggers.start.enabled,
                value: config.triggers.start.value
            },
            fail: {
                enabled: config.triggers.fail.enabled,
                value: config.triggers.fail.value
            },
            success: {
                enabled: config.triggers.success.enabled,
                value: config.triggers.success.value
            },
            "play-single": {
                enabled: config.triggers["play-single"].enabled
            },
            "play-combined": {
                enabled: config.triggers["play-combined"].enabled
            }
        })
    })), app.triggers.receive("change", (function (e) {
        config.triggers[e.id].value = e.value, config.triggers[e.id].enabled = e.enabled, app.triggers.send("change", {
            name: e.id,
            settings: {
                enabled: config.triggers[e.id].enabled,
                value: config.triggers[e.id].value
            }
        })
    })), app.about.receive("init", (function () {
        app.version().then((e => app.about.send("init", {
            version: e,
            platform: app.platform()
        })))
    })), app.about.receive("open", (e => app.tab.open(e))), app.webRequest && app.webRequest.media((e => app.extract.send("media", e))), app.config.receive("init", (function () {
        app.config.send("init", config.list())
    })), app.config.receive("pref", (function (e) {
        try {
            config.set(e.name, e.value)
        } catch (e) {
            app.notification(e.message)
        }
        app.config.send("pref", {
            name: e.name,
            value: config.get(e.name)
        })
    })), app.config.receive("reset", (function (e) {
        config.reset(e), app.config.send("pref", {
            name: e,
            value: config.get(e)
        })
    })), app.preview.receive("open", (e => app.tab.open(e))), app.startup((function () {})), app.arguments((function (e) {
        e && e.url && actions.download(e)
    }));
WebExtensions = WebExtensions || navigator.userAgent.includes("Chrome") ? chrome : browser, app = app || require("./firefox/firefox");
var myBgBackground = {
    sendTab: (e, t, n) => WebExtensions.tabs.sendMessage(parseInt(n), {
        method: e + "@myAd",
        data: t
    }),
    receive: (e, t) => WebExtensions.runtime.onMessage.addListener((function (n, i) {
        n.method === e + "@myAd" && i.url !== document.location.href && t(n.data)
    }))
};

function startNewDl(e, t, n = 2) {
    WebExtensions.tabs.create({
        url: t
    }, (t => {
        myBgBackground.receive("newDlMContentOk", (i => {
            myBgBackground.sendTab("download", {
                targetUrl: e,
                threads: n,
                dlmPageId: i
            }, t.id)
        }))
    }))
}
WebExtensions.tabs.onRemoved.addListener((function (e) {
    app.manager.terminateTask(e)
}));